<?php
/**
 * @brief Klasa encyjna Commodity
 * 
 * Obiekty tej klasy reprezentują rzeczywiste oraz abstrakcyjne dobra i usługi
 * oferowane na aukcjach. Na aukcjach moga być oferowane wyłącznie okreslone typy
 * towarów. Kazdy towar ma przyporzadkowany typ. Każdy towar ma określone miejsce
 * oraz czas w którym jest/będzie dostepny. Miejscem może być lokalizacja albo
 * połączenie międyz nimi. Czas dostawy może być określony w słowniku towarów
 * albo niezależnie. Zdefiniowane towary możan wykorzystać tylko przy jednej aukcji.
 */
class Application_Model_Commodity
{
    protected $_Commodity_id; /*!< Identyfikator towaru.*/
    protected $_CommodityType_id; /*!< Typ towaru.*/
    protected $_MarketEntity_id; /*!< Nazwa jednostki rynkowej definiującej towar. */
    protected $_CalendarPeriod_id; /*!< Identyfikator powiąznego terminu dostaw.*/
    protected $_NetworkNode_id; /*!< Identyfikator powiąznej lokalizacji. */ 
    protected $_NetworkArc_id; /*!< Identyfikator powiązanego połączenia.*/
    protected $_name; /*!< Nazwa towaru.*/ 
    protected $_description; /*!< Opis towaru.*/
    protected $_hasDeliveryTime; /*!< Meta-informacja czy towar ma okres dostaw z kalendarza.*/
    protected $_startTime; /*!< Data początku okresu dostawy. */
    protected $_endTime; /*!< Data zakończenia okresu dostawy.*/
    protected $_used; /*!< Meta-informacja czy towar był już wykorzystany w aukcji.*/
    
    protected $_Type; /*!< Typ towaru.*/
    protected $_CalendarPeriod; /*!< Okres dostawy z kalendarza*/
    protected $_temporaryShareFactor;

    /**
     * @brief Konstruktor 
     * 
     * Przyjmuje tablicę znaków i na jej podstawie uzupełnia pola,
     * przy pomocy setOptions.
     * @param array $options 
     */
    public function __construct(array $options = null) {
        if (is_array($options)) {
            $this->setOptions($options);
        }
    }

    /**
     * @brief Metoda uzupełniająca pola na podstawie wejściowej tablicy.
     * 
     * @param array $options
     * @return Obiekt tej klasy.
     */
    public function setOptions(array $options) {

        $methods = get_class_methods($this);

        foreach ($options as $key => $value) {

            $method = 'set' . ucfirst($key);

            if (in_array($method, $methods)) {

                $this->$method($value);
            }
        }
        return $this;
    }
    /**
     * @brief Metoda zwracająca meta-informację o tym, czy towar został już wykorzystany.
     *
     * @return 1 jak towar został wykorzystany, 0 w przeciwnym wypadku.
     */
    public function getUsed() {
        return $this->_used;
    }
    /**
     * @brief Metoda ustawiająca meta-informację o tym, czy towar został już wykorzystany.
     *
     * @param int $_used 
     */
    public function setUsed($_used) {
        $this->_used = $_used;
    }
    /**
     * @brief Metoda zwracająca identyfikator towaru.
     *
     * @return int 
     */
    public function getCommodity_id() {
        return $this->_Commodity_id;
    }
    /**
     * @brief Metoda ustawiająca identyfikator towaru.
     *
     * @param int $_Commodity_id 
     */
    public function setCommodity_id($_Commodity_id) {
        $this->_Commodity_id = $_Commodity_id;
    }
    /**
     * @brief Metoda zwracająca identyfikator typu towaru.
     *
     * @return int
     */
    public function getCommodityType_id() {
        return $this->_CommodityType_id;
    }
    /**
     * @brief Metoda ustawiająca identyfikator typu towaru.
     *
     * @param int $_CommodityType_id 
     */
    public function setCommodityType_id($_CommodityType_id) {
        $this->_CommodityType_id = $_CommodityType_id;
    }
    /**
     * @brief Metoda zwracająca identyfikator jednostki rynkowej, która zdefinowała towar.
     *
     * @return String 
     */
    public function getMarketEntity_id() {
        return $this->_MarketEntity_id;
    }
    /**
     * @brief Metoda ustawiająca identyfikator jednostki rynkowej, która zdefinowała towar.
     *
     * @param String $_MarketEntity_id 
     */
    public function setMarketEntity_id($_MarketEntity_id) {
        $this->_MarketEntity_id = $_MarketEntity_id;
    }
    /**
     * @brief Metoda zwracająca identyfikator terminu dostaw z klendarza.
     *
     * O ile towar, nie ma określonego indywidualnie terminu dostaw. 
     * @return int 
     */
    public function getCalendarPeriod_id() {
        return $this->_CalendarPeriod_id;
    }
    /**
     * @brief Metoda ustawiająca identyfikator terminu dostaw z klendarza.
     *
     * @param int $_CalendarPeriod_id 
     */
    public function setCalendarPeriod_id($_CalendarPeriod_id) {
        $this->_CalendarPeriod_id = $_CalendarPeriod_id;
    }
    /**
     * @brief Metoda zwracająca identyfikator lokalizacji w której towar będzie dostepny.
     * 
     * O ile towar nie jest przypisany do połączenia.
     * @return int 
     */
    public function getNetworkNode_id() {
        return $this->_NetworkNode_id;
    }
    /**
     * @brief Metoda ustawiająca identyfikator lokalizacji w której towar będzie dostepny.
     *
     * @param int $_NetworkNode_id 
     */
    public function setNetworkNode_id($_NetworkNode_id) {
        $this->_NetworkNode_id = $_NetworkNode_id;
    }
    /**
     * @brief Metoda zwracająca identyfikator połączenia w której towar będzie dostepny.
     *
     * @return int 
     */
    public function getNetworkArc_id() {
        return $this->_NetworcArc_id;
    }
    /**
     * @brief Metoda ustawiająca identyfikator połączenia w której towar będzie dostepny.
     *
     * @param int $_NetworcArc_id 
     */
    public function setNetworkArc_id($_NetworcArc_id) {
        $this->_NetworcArc_id = $_NetworcArc_id;
    }
    /**
     * @brief Metoda zwracająca nazwę towaru.
     *
     * @return String 
     */
    public function getName() {
        return $this->_name;
    }
    /**
     * @brief Metoda ustawiająca nazwę towaru.
     *
     * @param String $_name 
     */
    public function setName($_name) {
        $this->_name = $_name;
    }
    /**
     * @brief Metoda zwracająca opis towaru.
     *
     * @return String 
     */
    public function getDescription() {
        return $this->_description;
    }
    /**
     * @brief Metoda ustawiająca opis towaru.
     *
     * @param String $_description 
     */
    public function setDescription($_description) {
        $this->_description = $_description;
    }
    /**
     * @brief Metoda zwracająca meta-informację o sposobie określenia terminu dostawy.
     *
     * @return 1 jak wykorzystywany jest termin z kalendarza, 0 jak termin ustalany jest indywidualnie dla towaru.
     */
    public function getHasDeliveryTime() {
        return $this->_haseDeliveryTime;
    }
    /**
     * @brief Metoda ustawiająca meta-informację o sposobie określenia terminu dostawy.
     *
     * @param int $_haseDeliveryTime 
     */
    public function setHasDeliveryTime($_haseDeliveryTime) {
        $this->_haseDeliveryTime = $_haseDeliveryTime;
    }
    /**
     * @brief Metoda zwracająca datę rozpoczęcia indywidualnego okresu dostawy.
     * 
     * O ile dotyczy.
     * @return string 
     */
    public function getStartTime() {
        return $this->_startTime;
    }
    /**
     * @brief Metoda ustawiająca datę rozpoczęcia indywidualnego okresu dostawy.
     *
     * O ile dotyczy.
     * @param type $_startTime 
     */
    public function setStartTime($_startTime) {
        $this->_startTime = $_startTime;
    }
    /**
     * @brief Metoda zwracająca datę zakończenia indywidualnego okresu dostawy.
     *
     * O ile dotyczy.
     * @return string
     */
    public function getEndTime() {
        return $this->_endTime;
    }
    /**
     * @brief Metoda ustawiająca datę zakończenia indywidualnego okresu dostawy.
     *
     * @param string $_endTime 
     */
    public function setEndTime($_endTime) {
        $this->_endTime = $_endTime;
    }
    /**
     * @brief Metoda zwracająca nazwę typu towaru.
     *
     * @return String
     */
    public function getCommodityTypeName() {
            if(!isset($this->_Type)){
                $this->setCommodityType();
            }
            return $this->_Type->getName();
    }
    
    public function getCategoryName() {
            if(!isset($this->_Type)){
                $this->setCommodityType();
            }
            return $this->_Type->getCategoryName();
    }
    /**
     * @brief Metoda zwracająca typ towaru.
     *
     * @return type Application_Model_CommodityType
     */
    public function getCommodityType(){
        if(!isset($this->_Type)){
            $this->setCommodityType();
        } 
        return $this->_Type;
    }
    /**
     * @brief Metoda ustawiająca typ towaru.
     *
     * @return null 
     */
    public function setCommodityType() {
        $type_id = $this->getCommodityType_id();
        if(isset($type_id))
        {
            $mapper = new Application_Model_CommodityTypeMapper();
            $this->_Type = $mapper->find($type_id);
            return;
        }
        throw new Exception('Pusty obiekt');
        
    }

    /**
     * @brief Zwraca nazwę połączenia o podanym id w formie A - B. 
     *        
     * Gdzie A i B to nazwy lokalizacji.
     * 
     * @param int $id
     * @return String
     */
    public function getArcName($id) {
        $arcMapper = new Application_Model_NetworkArcMapper();
        $arc = $arcMapper->find($id);
        return $arc->getPredecessorName().' - '.$arc->getSuccessorName();
        
    }
    /**
     * @brief Zwraca nazwę lokalizacji o podanym id.
     * 
     * @param type $id
     * @return type 
     */
    public function getNodeName($id) {
        $nodeMapper = new Application_Model_NetworkNodeMapper();
        $node = $nodeMapper->find($id);
        return $node->getName();
    }
    
    public function getLocation() {
        $node_id = $this->getNetworkNode_id();
        $arc_id = $this->getNetworkArc_id();
        
        if(!empty($node_id))
            return $this->getNodeName($node_id);
        if(!empty($arc_id))
            return $this->getArcName($arc_id);
        return 'error';
    }
    
    public function getLocationType() {
        $node_id = $this->getNetworkNode_id();
        $arc_id = $this->getNetworkArc_id();
        
        if(!empty($node_id))
            return 'Lokalizacja';
        if(!empty($arc_id))
            return 'Połączenie';
        return 'error';
    }
    
    public function getBeginningOfDelivery() {
        
        $periodId = $this->getCalendarPeriod_id();
        $getTime = $this->getStartTime();

        if(!empty($periodId)) {
            $this->getCalendarPeriod();
            return $this->_CalendarPeriod->getStartTime();
        } elseif (!empty($getTime)) {
            return $getTime;
        } else {
            return 'error';
        }
    }
    
    public function getEndOfDelivery() {
        $periodId = $this->getCalendarPeriod_id();
        $getTime = $this->getEndTime();

        if(!empty($periodId)) {
            $this->getCalendarPeriod();
            return $this->_CalendarPeriod->getEndTime();

        } elseif (!empty($getTime)) {
            return $getTime;
        } else {
            return 'error';
        }
        
    }
    
    public function getCalendarPeriod() {
        if(empty($this->_CalendarPeriod))
            $this->setCalendarPeriod();
        return $this->_CalendarPeriod;
    }

    public function setCalendarPeriod() {
        $periodMapper = new Application_Model_CalendarPeriodMapper();
        $period = $periodMapper->find($this->_CalendarPeriod_id);
        $this->_CalendarPeriod = $period;
    }
    
    public function getTemporaryShareFactor() {
        return $this->_temporaryShareFactor;
    }

    public function setTemporaryShareFactor($temporaryShareFactor) {
        $this->_temporaryShareFactor = $temporaryShareFactor;
    }

    public function getShareFactor($user) {
        if($user == $this->_MarketEntity_id) {
            return $this->_temporaryShareFactor;
        } else {
            return -1 * $this->_temporaryShareFactor ;
        }
    }
}

